package com.abc.fast.server.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.abc.fast.common.constant.CacheConstants;
import com.abc.fast.common.utils.AssertUtil;
import com.abc.fast.common.utils.EncryptUtil;
import com.abc.fast.common.utils.RedisUtil;
import com.abc.fast.server.user.service.adapter.CodeAdapter;
import com.abc.fast.server.user.domain.dto.GenerateDto;
import com.abc.fast.server.user.domain.vo.req.CheckCodeParamsReq;
import com.abc.fast.server.user.domain.vo.resp.CheckCodeResp;
import com.abc.fast.server.user.service.CodeService;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class CodeServiceImpl implements CodeService {

    public static final int CODE_EXPIRE_TIME = 5;

    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @Override
    public CheckCodeResp generate(CheckCodeParamsReq req) {
        GenerateDto generateRandom = generateRandom(req);
        String image = createPic(generateRandom.getCode());
        return CodeAdapter.createCodeResp(image, generateRandom);
    }

    /**
     * 生成验证码和UUID
     * @param checkCodeParamsVo
     * @return
     */
    private GenerateDto generateRandom(CheckCodeParamsReq checkCodeParamsVo) {
        GenerateDto generateDto = new GenerateDto();
        String uuid = RandomUtil.randomString(12);
        String code = RandomUtil.randomNumbers(5);
        generateDto.setUuid(uuid);
        generateDto.setCode(code);
        RedisUtil.set(getKey(checkCodeParamsVo.getCheckCodeType() + "_" + uuid), code, CODE_EXPIRE_TIME, TimeUnit.MINUTES);
        return generateDto;
    }

    /**
     * 获取缓存的键
     * @param uuid
     * @return
     */
    private String getKey(String uuid){
        return CacheConstants.getKey(CacheConstants.LOGIN_CODE, uuid);
    }


    /**
     * 生成图形验证码
     * @return
     */
    private String createPic(String code) {
        // 生成图片验证码
        ByteArrayOutputStream outputStream = null;
        BufferedImage image = defaultKaptcha.createImage(code);

        outputStream = new ByteArrayOutputStream();
        String imgBase64Encoder = null;
        try {
            // 对字节数组Base64编码
            ImageIO.write(image, "png", outputStream);
            imgBase64Encoder = "data:image/png;base64," + EncryptUtil.encodeBase64(outputStream.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return imgBase64Encoder;
    }

    @Override
    public Boolean verify(String key, String code) {
        String codeStr = RedisUtil.getStr(key);
        AssertUtil.isNotEmpty(codeStr, "验证码失效，请刷新重试");

        return codeStr.equals(code);
    }
}
